/******************************************************************************************************
Copyright (C) 2013 Mestrelab Research S.L. All rights reserved.

This file is part of the MNova scripting toolkit.

Authorized users of MNova Software may use this file freely, but this file is provided AS IS
with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
*****************************************************************************************************/

/*jslint plusplus: true, bitwise: true, indent: 4*/

if (!String.prototype.trim) {
	String.prototype.trim = function () {
		"use strict";

		return this.replace(/^\s+/g, "").replace(/\s+$/g, "");
	};
}

//"String pattern {0} with items {1} and {2}".format("Some Data",5, new Date());
if (!String.prototype.format) {
	String.prototype.format = function () {
		"use strict";
		var i,
			formatted = this;

		for (i = 0; i < arguments.length; i++) {
			formatted = formatted.replace(new RegExp("\\{" + i + "\\}", "g"), arguments[i].toString());
		}
		return formatted;
	};
}

if (!String.prototype.formatMap) {
	String.prototype.formatMap = function (aMap) {
		"use strict";

		var i,
			formatted = this;

		for (i in aMap) {
			if (aMap.hasOwnProperty(i)) {
				formatted = formatted.replace(new RegExp("\\{" + i + "\\}", "g"), aMap[i]);
			}
		}
		return formatted;
	};
}

if (!String.prototype.startsWith) {
	String.prototype.startsWith = function (aStr) {
		"use strict";

		return this.indexOf(aStr) === 0;
	};
}

if (!String.prototype.endsWith) {
	String.prototype.endsWith = function (aStr) {
		"use strict";
		if (this.lastIndexOf(aStr) !== -1) {
			return this.lastIndexOf(aStr) === this.length - aStr.length;
		}
		return false;
	};
}

if (!String.prototype.rpad) {
	String.prototype.rpad = function (aPadString, aLength) {
		"use strict";
		var str = this.toString();

		while (str.length < aLength) {
			str = str + aPadString;
		}
		return str;
	};
}

if (!String.prototype.lpad) {
	String.prototype.lpad = function (aPadString, aLength) {
		"use strict";
		var str = this.toString();

		while (str.length < aLength) {
			str = aPadString + str;
		}
		return str;
	};
}

if (!String.prototype.toBase64) {
	String.prototype.toBase64 = function () {
		"use strict";
		var str, chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, keyStr, input, output;

		str = this;
		keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
		output = "";
		i = 0;

		input = str.toUtf8();
		while (i < input.length) {

			chr1 = input.charCodeAt(i++);
			chr2 = input.charCodeAt(i++);
			chr3 = input.charCodeAt(i++);

			enc1 = chr1 >> 2;
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
			enc4 = chr3 & 63;

			if (isNaN(chr2)) {
				enc3 = enc4 = 64;
			} else if (isNaN(chr3)) {
				enc4 = 64;
			}
			output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + keyStr.charAt(enc3) + keyStr.charAt(enc4);
		}
		return output;
	};
}

if (!String.prototype.fromBase64) {
	String.prototype.fromBase64 = function () {
		"use strict";
		var str, chr1, chr2, chr3, enc1, enc2, enc3, enc4, i, keyStr, input, output;

		str = this;
		keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
		output = "";
		i = 0;

		/*jslint regexp: true */
		input = str.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		/*jslint regexp: false */
		while (i < input.length) {

			enc1 = keyStr.indexOf(input.charAt(i++));
			enc2 = keyStr.indexOf(input.charAt(i++));
			enc3 = keyStr.indexOf(input.charAt(i++));
			enc4 = keyStr.indexOf(input.charAt(i++));

			chr1 = (enc1 << 2) | (enc2 >> 4);
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
			chr3 = ((enc3 & 3) << 6) | enc4;

			output = output + String.fromCharCode(chr1);

			if (enc3 !== 64) {
				output = output + String.fromCharCode(chr2);
			}
			if (enc4 !== 64) {
				output = output + String.fromCharCode(chr3);
			}
		}
		output = output.fromUtf8();
		return output;
	};
}

if (!String.prototype.toUtf8) {
	String.prototype.toUtf8 = function () {
		"use strict";
		var str, string, utfText, n, c;

		str = this;
		string = string.replace(/\r\n/g, "\n");
		utfText = "";

		for (n = 0; n < string.length; n++) {
			c = string.charCodeAt(n);
			if (c < 128) {
				utfText += String.fromCharCode(c);
			} else if ((c > 127) && (c < 2048)) {
				utfText += String.fromCharCode((c >> 6) | 192);
				utfText += String.fromCharCode((c & 63) | 128);
			} else {
				utfText += String.fromCharCode((c >> 12) | 224);
				utfText += String.fromCharCode(((c >> 6) & 63) | 128);
				utfText += String.fromCharCode((c & 63) | 128);
			}
		}
		return utfText;
	};
}

if (!String.prototype.fromUtf8) {
	String.prototype.fromUtf8 = function () {
		"use strict";
		var str, string, utfText, i, c, c1, c2, c3;

		str = this;
		string = "";
		i = 0;
		c = 0;
		c1 = 0;
		c2 = 0;
		c3 = 0;

		utfText = str;
		while (i < utfText.length) {

			c = utfText.charCodeAt(i);
			if (c < 128) {
				string += String.fromCharCode(c);
				i++;
			} else if ((c > 191) && (c < 224)) {
				c2 = utfText.charCodeAt(i + 1);
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
				i += 2;
			} else {
				c2 = utfText.charCodeAt(i + 1);
				c3 = utfText.charCodeAt(i + 2);
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
				i += 3;
			}
		}
		return string;
	};
}
